#ifndef PROTOCAL_H
#define PROTOCAL_H

#include <stdint.h>
#include "string.h"

#if defined(__cplusplus) || defined(c_plusplus) //跨平台定义方式
extern "C"{
#endif

//开启前期调试功能（非通讯）
//#define debug_f
#ifdef debug_f								
//用于调试时的输出变量
extern uint16_t u6_debug_value;
#endif

	

#define PROTOCAL_SLAVE_ADDR     		(0x38)		//从机，485机内总线协议中电源地址定义

#define PROTOCAL_START_FLAG     		(0x7E)
#define PROTOCAL_END_FLAG     			(0x7E)
#define PROTOCAL_ESCAPE_FLAG     		(0x7D)
#define PROTOCAL_GETREQUEST    			(0x10)		//查询请求/空应答
#define PROTOCAL_UPLOAD    				(0x11)		//数据下发/数据上报
#define PROTOCAL_GETDEVICE    			(0x12)		//拓扑查询/拓扑应答
#define PROTOCAL_GETVERION    			(0x13)		//版本请求/版本应答
#define PROTOCAL_NOTREQUEST    			(0x14)		//指令不支持应答


#define PROTOCAL_TEST_START_FLAG     	(0xEB)
#define PROTOCAL_HOST_ID     			(0x90)
#define PROTOCAL_SLAVE_ID     			(0x91)
#define PROTOCAL_CMD_QUERY     			(0x00)
#define PROTOCAL_CMD_AC_DROPOFF     	(0x60)
#define PROTOCAL_CMD_EMERGENT     		(0x61)
#define PROTOCAL_CMD_RECOVER_EMERGENT	(0x80)
#define PROTOCAL_CMD_RECOVER_MAIN_POWER	(0x81)
#define PROTOCAL_CMD_POWEROFF     		(0x70)
#define PROTOCAL_CMD_CALIB		    	(0xDF)
#define PROTOCAL_CMD_TSET		   		(0x0B)

#define PROTOCAL_CMD_QUERY_VERSION     	(0xD1)		//查询软件版本
#define PROTOCAL_CMD_DEBUG		     	(0xD2)		//设置调试输出模式
#define PROTOCAL_CMD_SEQUENCE_1		    (0xEF)		//命令确认序列1
#define PROTOCAL_CMD_SEQUENCE_2		    (0xDE)		//命令确认序列2


extern uint8_t 	gu8_IsQueryversion;
extern uint8_t  gu8_Isdebug;
extern uint8_t 	gu8_com_data_init_end;					//开机等待数据初始化完成再上传
extern uint8_t	gu8_com_data_deal_end;
extern uint8_t	gu8_EmerFlag;
extern uint8_t  gu8_com_type_version;

extern uint8_t	gu8_uarthostRxStatusFlag;
extern uint8_t	gu8_uarthostRxdone;

extern volatile uint8_t  gu8_uart_host_rx_remain;
extern volatile uint8_t  gu8_uart_host_tx_remain;
#if 0
extern volatile uint8_t  gu8_uart_host_rx_rev_len;	
extern volatile uint8_t  gu8_uart_host_rx_index;
extern volatile uint8_t  gu8_uart_host_rx_trace;
extern volatile uint8_t  gu8_uart_host_rx_tail;
#endif
extern volatile uint8_t  gu8_uart_host_tx_index;
extern volatile uint8_t  gu8_uart_host_tx_trace;

#define PROTOCAL_BUF_SIZE   64
#define USART_BUFFER_SIZE	64

extern uint8_t 	gu8_uart_host_send[PROTOCAL_BUF_SIZE];
#if 0
extern uint8_t 	gu8_uart_host_recv[PROTOCAL_BUF_SIZE];
#endif
extern uint8_t 	gu8_uart_host_rx_buf[USART_BUFFER_SIZE];
extern uint8_t 	gu8_uart_host_tx_buf[USART_BUFFER_SIZE];
extern uint8_t	gu8_escape_send_data[PROTOCAL_BUF_SIZE];
extern uint8_t	gu8_escape_over_send_data[PROTOCAL_BUF_SIZE];

#define uart_msg_rec_buffer_num  	3
typedef struct UART_MSG_REV
{
	uint8_t u8is_used;			//占用标志位
	uint8_t u8len;				//序号对应的信息长度
	uint8_t msg[80];			//序号对应的信息
}Uart_Msg_Rec;
extern Uart_Msg_Rec  gst_uart_msg_rec[uart_msg_rec_buffer_num];

typedef struct _ctrl			//485机内总线协议包---控制字段
{
	uint8_t DI:1;				//帧数据方向，从机默认为1
	uint8_t NS:3;				//发送帧序号
	uint8_t PF:1;				//查询/终止指示符
	uint8_t NR:3;				//期望接收帧序号（bit7-5）
}Bus_Ctrl_t;

typedef struct _info			//485机内总线协议包---信息字段
{
	uint8_t cmd;				//命令字
	uint8_t len;				//数据长度
	uint8_t data[80];			//数据
}Bus_Info_t;

typedef struct buspack			//485机内总线协议包
{
	uint8_t addr;				//从机地址
	Bus_Ctrl_t ctrl;			//控制字段
	Bus_Info_t info;			//信息字段
	uint8_t FCS_H;				//CRC16高字节
	uint8_t FCS_L;				//CRC16低字节
}Bus_Pack_t;
extern Bus_Pack_t  gst_bus_pack;


void Protocal_Init(void);								//初始化通讯相关变量

uint8_t protocal_make_cmd_data(uint8_t cmd, const uint8_t* data, uint8_t len, uint8_t * pro_send_data); 		//组帧

uint8_t ChkSum(uint8_t *dataBuf, uint8_t dataLen);		//和校验

uint16_t protocal_make_send_data(const Bus_Pack_t pack, uint8_t *pro_send_data, uint8_t buff_size);					//组总线帧

/**
 * @brief pro_deal_recv_data
 * 对收到的数据验证CRC，并应答通信方；
 * @param data 待处理数组
 * @return void
 */
void pro_deal_recv_data(uint8_t *data, uint8_t len);


/**
 * @brief Judge_Uart_Receive_Done
 *      判断通讯状态，开始或是结束
 * @return void
 */
void Judge_Uart_Receive_Done(void);		


#if defined(__cplusplus) || defined(c_plusplus) //跨平台定义方式
}
#endif
#endif // PROTOCAL_H

